import { Server } from 'hyper-express';
import 'dotenv';
import api_router from './app/routes'
import ignore_favicon_middleware from './app/middlewares/pages/favicon'
import log from './app/helpers/logger';
// import * as cookieParser from 'cookie-parser';
import deserializeUser from './app/middlewares/auth/deserializeUser';
import rateLimiterMiddleware from './app/middlewares/rateLimit';
//import * as cors from 'cors';
import { measureRequest } from './app/middlewares/measureRequest';
import LiveDirectory from 'live-directory';
//import { SessionEngine, Session }  from 'hyper-express-session';
import { createClient } from '@redis/client';
import redis from './app/lib/redis';
import path from 'path'
import fs from 'fs'
import wsRouter from './app/websocket/wsRouter';
import requireUser from './app/middlewares/auth/requireUser';
import { crontab } from './app/middlewares/crontab';
import { PrismaClient as PgClient } from '../prisma/generated/uctoo'

const prisma = new PgClient({
  log: ['query', 'info', 'warn', 'error'],
})
/* 
const my = new MyClient({
  log: ['query', 'info', 'warn', 'error'],
})*/

const { FRONTEND_URL, NODE_ENV, CERT_FILE_NAME, KEY_FILE_NAME, LIVE_DIRECTORY } = process.env;
const isProduction = NODE_ENV === 'production';
const SERVER_OPTIONS = {
  cert_file_name: CERT_FILE_NAME,    // API_URL只用http时需要注释掉SSL相关配置
  key_file_name: KEY_FILE_NAME,      // API_URL只用http时需要注释掉SSL相关配置
  max_body_length: 100 * 1024 * 1024
};
// Create a LiveDirectory instance to virtualize directory with our assets
// Specify the "path" of the directory we want to consume using this instance as the first argument
//windows OS LiveDirectory like D:/UCT/products/gitee/uctoo-backend-v3-beta/src/assets   , linux OS /var/www/website/files
const LiveAssets = new LiveDirectory(LIVE_DIRECTORY, {
  // Optional: Configure filters to ignore or include certain files, names, extensions etc etc.
  filter: {
    keep: {
      // Something like below can be used to only serve images, css, js, json files aka. most common web assets ONLY
      extensions: ['css', 'js', 'json', 'png', 'jpg', 'jpeg']
    },
    ignore: (path) => {
      // You can define a function to perform any kind of matching on the path of each file being considered by LiveDirectory
      // For example, the below is a simple dot-file ignore match which will prevent any files starting with a dot from being loaded into live-directory
      return path.startsWith('.');
    },
  },

  // Optional: You can customize how LiveDirectory caches content under the hood
  cache: {
    // The parameters below can be tuned to control the total size of the cache and the type of files which will be cached based on file size
    // For example, the below configuration (default) should cache most <1 MB assets but will not cache any larger assets that may use a lot of memory
    // In the scenario that LiveDirectory encounters an uncached file, It will s
    max_file_count: 250, // Files will only be cached up to 250 MB of memory usage
    max_file_size: 1024 * 1024, // All files under 1 MB will be cached
  },
});

const app = new Server(SERVER_OPTIONS);  //创建服务器应用

app.use('/favicon.ico', ignore_favicon_middleware);  //ignore favicon
//需要根目录域名文件验证的场景，可取消注释以下部分进行支持，将文件放置在assets目录下，修改get文件名。
/*
app.get('/4199628196.txt', (request, response) => {

  const dir = path.resolve('assets')
  const file = path.join(dir, request.path.replace('/assets', ''))

  const type = 'text/plain'
  const stream = fs.createReadStream(file)

  stream.on('open', () => {
    response.set('Content-Type', type)
    stream.pipe(response)
  })
});*/
// Create GET route to serve 'Hello World'
app.get('/hello', (request, response) => {
  log.info('HELLO');
  response.send('Hello World');
});

//check prisma works
app.get('/prismacheck', async (request, response) => {
  // A `main` function so that you can use async/await
  const allLinkss = await prisma.link.findMany()
  // PostgreSQL 查询
  //const postgresUsers = await pg.admin_applet.findMany()

// MySQL 查询
//const mysqlCheck = await my.api_category.findMany() 
//log.info(mysqlCheck);
  // use `console.dir` to print nested objects
  log.info(allLinkss);
  
  response.status(200).json(allLinkss);
})

// Create static serve route to serve frontend assets
app.get('/assets/*', (request, response) => {
  // Strip away '/assets' from the request path to get asset relative path
  // Lookup LiveFile instance from our LiveDirectory instance.
  const path = request.path.replace('/assets', '');
  const file = LiveAssets.get(path);

  // Return a 404 if no asset/file exists on the derived path
  if (file === undefined) return response.status(404).send();

  const fileParts = file.path.split(".");
  const extension = fileParts[fileParts.length - 1];

  // Retrieve the file content and serve it depending on the type of content available for this file
  const content = file.content;
  if (content instanceof Buffer) {
    // Set appropriate mime-type and serve file content Buffer as response body (This means that the file content was cached in memory)
    return response.type(extension).send(content);
  } else {
    // Set the type and stream the content as the response body (This means that the file content was NOT cached in memory)
    return response.type(extension).stream(content);
  }
});

// Some examples of how the above route will map & serve requests:
// [GET /assets/images/logo.png] >> [/var/www/website/files/images/logo.png]
// [GET /assets/js/index.js] >> [/var/www/website/files/js/index.js]

//If user requests server favicon
//app.get('/favicon.ico', (req, res) => {
//  res.sendFile(__dirname + '/assets/favicon.ico');
//});

//Heatlhcheck route for checking if service is online
app.get('/healthcheck', (req, res) => {
  res.status(200).end();
});
//Handle all of unsuported routes
app.get('/*', (req, res) => {
  res.status(404).send('Unsupported route');
});
let cors = require('cors');
app.use(cors({ credentials: true, origin: isProduction ? FRONTEND_URL : '*' }));

let cookieParser = require('cookie-parser');
app.use(cookieParser());

app.use(deserializeUser);
app.use(rateLimiterMiddleware);
if (!isProduction) {
  app.use(measureRequest);
}

app.use('/api', api_router);  //api url example https://api.uctoo.com/api/uctoo/auth/login

/** socket */
app.use('/ws', wsRouter);
//查询crontab表生成计划任务
//app.use(crontab);

export default app;